﻿<script setup lang="ts" name="CropperWrap">
import type Cropper from 'cropperjs'
type CropendResult = {
  imgBase64: string;
  imgInfo: Cropper.Data;
}
const props = defineProps({
  circled: { type: Boolean, default: true },
  value: { type: String }
})

const emit = defineEmits(['fileChange'])

let filename = ''
const src = ref(props.value || '')
const previewSource = ref('')
const cropper = ref<Cropper>()
let scaleX = 1
let scaleY = 1

const handleBeforeUpload = (file: File) => {
  const reader = new FileReader()
  reader.readAsDataURL(file)
  src.value = ''
  previewSource.value = ''
  reader.onload = function (e) {
    src.value = (e.target?.result as string) ?? ''
    filename = file.name
  }
  return false
}

const handleCropend = ({ imgBase64, imgInfo }: CropendResult) => {
  previewSource.value = imgBase64
  emit('fileChange', {
    filename: filename,
    value: previewSource.value,
    imgInfo: imgInfo
  })
}

const handleReady = (cropperInstance: Cropper) => {
  cropper.value = cropperInstance
  emit('fileChange', {
    filename: filename,
    value: previewSource.value
  })
}

const handlerToolbar = (event: string, arg?: number) => {
  if (event === 'scaleX') {
    scaleX = arg = scaleX === -1 ? 1 : -1
  }
  if (event === 'scaleY') {
    scaleY = arg = scaleY === -1 ? 1 : -1
  }
  cropper?.value?.[event]?.(arg)
}
</script>

<template>
  <div class="cropper-wrap">
    <div class="cropper-left">
      <div class="cropper-content">
        <CropperImage v-if="src" :src="src" height="330px" :circled="props.circled" @cropend="handleCropend" @ready="handleReady" />
      </div>
      <div class="cropper-toolbar">
        <div class="cropper-upload">
          <el-upload :fileList="[]" :show-file-list="false" accept="image/*" :beforeUpload="handleBeforeUpload">
            <el-tooltip :content="$t('buttons.buttonCropperSelectImage')" placement="bottom">
              <el-button size="small" type="primary"><svg-icon icon="ad:upload-outlined"></svg-icon></el-button>
            </el-tooltip>
          </el-upload>
        </div>
        <div class="cropper-operate">
          <el-tooltip :content="$t('buttons.buttonReset')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('reset')"><svg-icon icon="ad:reload-outlined"></svg-icon></el-button>
          </el-tooltip>
          <el-tooltip :content="$t('buttons.buttonRotateLeft')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('rotate', -45)"><svg-icon icon="ad:rotate-left-outlined"></svg-icon></el-button>
          </el-tooltip>
          <el-tooltip :content="$t('buttons.buttonRotateRight')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('rotate', 45)"><svg-icon icon="ad:rotate-right-outlined"></svg-icon></el-button>
          </el-tooltip>
          <el-tooltip :content="$t('buttons.buttonHorizontalFlip')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('scaleX')"><svg-icon icon="ci:horizontal-flip"></svg-icon></el-button>
          </el-tooltip>
          <el-tooltip :content="$t('buttons.buttonVerticalFlip')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('scaleY')"><svg-icon icon="ci:vertical-flip"></svg-icon></el-button>
          </el-tooltip>
          <el-tooltip :content="$t('buttons.buttonZoomIn')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('zoom', 0.1)"><svg-icon icon="ad:zoom-in-outlined"></svg-icon></el-button>
          </el-tooltip>
          <el-tooltip :content="$t('buttons.buttonZoomOut')" placement="bottom">
            <el-button size="small" type="primary" :disabled="!src" @click="handlerToolbar('zoom', -0.1)"><svg-icon icon="ad:zoom-out-outlined"></svg-icon></el-button>
          </el-tooltip>
        </div>
      </div>
    </div>
    <div :class="['cropper-right', props.circled ? 'is-circle' : '']">
      <div class="cropper-preview">
        <img :src="previewSource" v-if="previewSource" />
      </div>
      <div class="cropper-group">
        <el-avatar v-if="previewSource" :src="previewSource" :size="32" :shape="props.circled ? 'circle' : 'square'" />
        <el-avatar v-if="previewSource" :src="previewSource" :size="48" :shape="props.circled ? 'circle' : 'square'" />
        <el-avatar v-if="previewSource" :src="previewSource" :size="64" :shape="props.circled ? 'circle' : 'square'" />
        <el-avatar v-if="previewSource" :src="previewSource" :size="96" :shape="props.circled ? 'circle' : 'square'" />
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.cropper-wrap{
  display: flex;
  flex-direction: row;

  .cropper-left,.cropper-right{
    height: 360px;
  }

  .cropper-left{
    width: 55%;
  }

  .cropper-right{
    width: 45%;
    padding-left: var(--el-space);

    &.is-circle{
      .cropper-preview{
        border-radius: 50%;
      }
    }
  }

  .cropper-content{
    height: 330px;
    background: #eeeeee;
    background-image: linear-gradient(
      45deg,
      rgba(0, 0, 0, 0.25) 25%,
      transparent 0,
      transparent 75%,
      rgba(0, 0, 0, 0.25) 0
    ),
      linear-gradient(
      45deg,
      rgba(0, 0, 0, 0.25) 25%,
      transparent 0,
      transparent 75%,
      rgba(0, 0, 0, 0.25) 0
    );
    background-position: 0 0, 12px 12px;
    background-size: 24px 24px;
  }

  .cropper-toolbar{
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 6px;

    :deep(.el-upload){
      vertical-align: top;
    }

    .el-button+.el-button{
      margin-left: 6px;
    }

    .el-button--small{
      padding: 5px 7px;
    }
  }

  .cropper-preview{
    width: 224px;
    height: 224px;
    margin: 0 auto;
    overflow: hidden;
    border: 1px solid var(--el-border-color-lighter);

    img{
      width: 100%;
      height: 100%;
    }
  }

  .cropper-group{
    display: flex;
    align-items: center;
    justify-content: space-around;
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--el-border-color-lighter);
  }
}
</style>
